﻿using System;
using System.Collections.Generic;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.Adapters;
using EPiServer.UI.WebControls;
using TemplateFoundation.PageTypeIcons.IconHandlers;
using TemplateFoundation.PageTypes;

namespace TemplateFoundation.PageTypeIcons {

    /// <summary>
    /// <para>Adapter for the <see cref="PageTreeView" /> control that adds support to add custom icons to the page tree in EPiServer.</para>
    /// </summary>
    public class PageTreeViewAdapter : HierarchicalDataBoundControlAdapter {
        
        #region Fields
        private static readonly string _nodeIconCssClass = "typeicon";
        private static readonly string _statusIconCssClass = "statusicon";
        private static readonly string _statusIconContainerCssClass = "iconcontainer";
        private List<IconHandlerBase> _nodeIconHandlers = new List<IconHandlerBase>();
        private List<IconHandlerBase> _statusIconHandlers = new List<IconHandlerBase>();
        #endregion

        #region Properties
        /// <summary>
        /// <para>Retrieves a strongly typed reference to the <see cref="PageTreeView" /> control associated with this <see cref="PageTreeViewAdapter" />.</para>
        /// </summary>
        /// <returns>The <see cref="T:System.Web.UI.WebControls.HierarchicalDataBoundControl" /> associated with the current instance of <see cref="T:System.Web.UI.WebControls.Adapters.HierarchicalDataBoundControlAdapter"></see>.</returns>
        protected new PageTreeView Control {
            get {
                return base.Control as PageTreeView;
            }
        }
        #endregion

        #region Methods

        /// <summary>
        /// <para>Overrides the <see cref="M:System.Web.UI.Control.OnInit(System.EventArgs)" /> method for the associated control.</para>
        /// </summary>
        /// <param name="e">A <see cref="T:System.EventArgs" /> that contains the event data.</param>
        protected override void OnInit(EventArgs e) {
            base.OnInit(e);
            if (Control == null)
                throw new InvalidOperationException("This Adapter can only be used with the EPiServer.WebControls.PageTreeView. Check your .browser settings file.");

            Control.PageTreeViewItemDataBound += Control_PageTreeViewItemDataBound;
        }

        private void Control_PageTreeViewItemDataBound(object sender, PageTreeViewEventArgs e) {
            AddTreeNodeIcons(e.Item);
        }

        /// <summary>
        /// Sets the tree icon for the specified <see cref="PageTreeNode"/>.
        /// </summary>
        /// <param name="node">The node.</param>
        protected virtual void AddTreeNodeIcons(PageTreeNode node) {
            if (node == null)
                throw new ArgumentNullException("node");

            var page = node.DataItem as PageTypeBase;
            if (page != null) {
                Image icon = null;

                // Check all the specified handlers for node icon if not already set
                if (!node.HasNodeIcon()) {
                    icon = page.GetPageTypeIcon();
                    if (icon != null) {
                        icon.CssClass = string.Format("{0} {1}", _nodeIconCssClass, icon.Attributes["class"]).TrimEnd();
                        node.TemplateContainer.Controls.AddAt(0, icon);
                    }
                }


                // Add status icons
                Control statusIconContainer = GetStatusIconContainer(node.TemplateContainer.Controls);
                if (statusIconContainer != null) {
                    foreach (IconHandlerBase handler in page.GetStatusIconHandlers()) {
                        icon = handler.GetIcon(page);
                        if (icon != null) {
                            icon.CssClass = string.Format("{0} {1}", _statusIconCssClass, icon.Attributes["class"]).TrimEnd();
                            statusIconContainer.Controls.Add(icon);
                        }
                    }
                }
            }
        }

        /// <summary>
        /// Gets the container control where status icons are placed.
        /// </summary>
        /// <param name="nodeControls">The node control collection.</param>
        /// <returns>Container control if found; otherwise null.</returns>
        protected virtual Control GetStatusIconContainer(ControlCollection nodeControls) {
            if (nodeControls != null) {
                // Container should be at the end, so start from the back
                for (int i = nodeControls.Count - 1; i >= 0; i--) {
                    WebControl container = nodeControls[i] as WebControl;
                    if (container != null && String.Equals(_statusIconContainerCssClass, container.CssClass)) {
                        return container;
                    }
                }
            }
            return null;
        }

        #endregion

    }
}